home *** CD-ROM | disk | FTP | other *** search
- /*
- ** find file types by using a modified "magic" file
- **
- ** based on file v3.22 by Ian F. Darwin (see below)
- **
- ** For each entry in the magic file, the message MUST start with
- ** two 4 character strings which are the CREATOR and TYPE for the
- ** Mac file. Any continuation lines are ignored. e.g magic entry
- ** for a GIF file:
- **
- ** 0 string GIF8 8BIM GIFf
- ** >4 string 7a \b, version 8%s,
- ** >4 string 9a \b, version 8%s,
- ** >6 leshort >0 %hd x
- ** >8 leshort >0 %hd,
- ** #>10 byte &0x80 color mapped,
- ** #>10 byte&0x07 =0x00 2 colors
- ** #>10 byte&0x07 =0x01 4 colors
- ** #>10 byte&0x07 =0x02 8 colors
- ** #>10 byte&0x07 =0x03 16 colors
- ** #>10 byte&0x07 =0x04 32 colors
- ** #>10 byte&0x07 =0x05 64 colors
- ** #>10 byte&0x07 =0x06 128 colors
- ** #>10 byte&0x07 =0x07 256 colors
- **
- ** Just the "8BIM" "GIFf" will be used whatever the type GIF file
- ** it is.
- **
- ** Modified for mkhybrid James Pearson 19/5/98
- */
-
- /*
- * file - find type of a file or files - main program.
- *
- * Copyright (c) Ian F. Darwin, 1987.
- * Written by Ian F. Darwin.
- *
- * This software is not subject to any license of the American Telephone
- * and Telegraph Company or of the Regents of the University of California.
- *
- * Permission is granted to anyone to use this software for any purpose on
- * any computer system, and to alter it and redistribute it freely, subject
- * to the following restrictions:
- *
- * 1. The author is not responsible for the consequences of use of this
- * software, no matter how awful, even if they arise from flaws in it.
- *
- * 2. The origin of this software must not be misrepresented, either by
- * explicit claim or by omission. Since few users ever read sources,
- * credits must appear in the documentation.
- *
- * 3. Altered versions must be plainly marked as such, and must not be
- * misrepresented as being the original software. Since few users
- * ever read sources, credits must appear in the documentation.
- *
- * 4. This notice may not be removed or altered.
- */
- #ifndef lint
- static char *moduleid =
- "@(#)$Id: file.c,v 1.38 1997/01/15 19:28:35 christos Exp $";
- #endif /* lint */
-
- #include <mconfig.h>
- #include <stdio.h>
- #include <stdxlib.h>
- #include <strdefs.h>
- #include <sys/types.h>
- #include <sys/param.h> /* for MAXPATHLEN */
- #include <sys/stat.h>
- #include <fcntl.h> /* for open() */
- #if (__COHERENT__ >= 0x420)
- # include <sys/utime.h>
- #else
- # ifdef USE_UTIMES
- # include <sys/time.h>
- # else
- # include <utime.h>
- # endif
- #endif
- #include <unistd.h> /* for read() */
-
- #include <netinet/in.h> /* for byte swapping */
-
- #include "patchlevel.h"
- #include "file.h"
-
- int /* Global command-line options */
- #ifdef DEBUG
- debug = 1, /* debugging */
- #else
- debug = 0, /* debugging */
- #endif /* DEBUG */
- lflag = 0, /* follow Symlinks (BSD only) */
- zflag = 0; /* follow (uncompress) compressed files */
-
- int /* Misc globals */
- nmagic = 0; /* number of valid magic[]s */
-
- struct magic *magic; /* array of magic entries */
-
- char *magicfile; /* where magic be found */
-
- char *progname; /* used throughout */
- int lineno; /* line number in the magic file */
-
- char * get_magic_match __PR((const char *inname));
- void clean_magic __PR((void));
-
- #if 0
- static int byteconv4 __P((int, int, int));
- static short byteconv2 __P((int, int, int));
- #endif
-
- #if 0
- /*
- * byteconv4
- * Input:
- * from 4 byte quantity to convert
- * same whether to perform byte swapping
- * big_endian whether we are a big endian host
- */
- static int
- byteconv4(from, same, big_endian)
- int from;
- int same;
- int big_endian;
- {
- if (same)
- return from;
- else if (big_endian) /* lsb -> msb conversion on msb */
- {
- union {
- int i;
- char c[4];
- } retval, tmpval;
-
- tmpval.i = from;
- retval.c[0] = tmpval.c[3];
- retval.c[1] = tmpval.c[2];
- retval.c[2] = tmpval.c[1];
- retval.c[3] = tmpval.c[0];
-
- return retval.i;
- }
- else
- return ntohl(from); /* msb -> lsb conversion on lsb */
- }
-
- /*
- * byteconv2
- * Same as byteconv4, but for shorts
- */
- static short
- byteconv2(from, same, big_endian)
- int from;
- int same;
- int big_endian;
- {
- if (same)
- return from;
- else if (big_endian) /* lsb -> msb conversion on msb */
- {
- union {
- short s;
- char c[2];
- } retval, tmpval;
-
- tmpval.s = (short) from;
- retval.c[0] = tmpval.c[1];
- retval.c[1] = tmpval.c[0];
-
- return retval.s;
- }
- else
- return ntohs(from); /* msb -> lsb conversion on lsb */
- }
- #endif
-
- /*
- * get_magic_match - get the CREATOR/TYPE string
- * based on the original process()
- */
- char *
- get_magic_match(inname)
- const char *inname;
- {
- int fd = 0;
- unsigned char buf[HOWMANY+1]; /* one extra for terminating '\0' */
- struct stat sb;
- int nbytes = 0; /* number of bytes read from a datafile */
- char *match;
-
- /* check the file is regular and non-zero length */
- if (stat(inname, &sb) != 0)
- return 0;
-
- if (sb.st_size == 0 || ! S_ISREG(sb.st_mode))
- return 0;
-
- if ((fd = open(inname, O_RDONLY)) < 0)
- return 0;
-
- /*
- * try looking at the first HOWMANY bytes
- */
- if ((nbytes = read(fd, (char *)buf, HOWMANY)) == -1)
- return 0;
-
- if (nbytes == 0)
- return 0;
- else {
- buf[nbytes++] = '\0'; /* null-terminate it */
- match = softmagic(buf, nbytes);
- }
-
- #ifdef RESTORE_TIME
- /* really no point as we going to access the file later anyway */
- {
- /*
- * Try to restore access, modification times if read it.
- */
- # ifdef USE_UTIMES
- struct timeval utsbuf[2];
- utsbuf[0].tv_sec = sb.st_atime;
- utsbuf[1].tv_sec = sb.st_mtime;
-
- (void) utimes(inname, utsbuf); /* don't care if loses */
- # else
- struct utimbuf utbuf;
-
- utbuf.actime = sb.st_atime;
- utbuf.modtime = sb.st_mtime;
- (void) utime(inname, &utbuf); /* don't care if loses */
- # endif
- #endif
- (void) close(fd);
-
- return(match);
- }
-
- /*
- * clean_magic - deallocate memory used
- */
- void
- clean_magic()
- {
- if (magic)
- free(magic);
- }
-
-
- #ifdef MAIN
- main(argc, argv)
- int argc;
- char **argv;
- {
- char *ret;
- char creator[5];
- char type[5];
-
- if (argc < 3)
- exit(1);
-
- init_magic(argv[1]);
-
- ret = get_magic_match(argv[2]);
-
- if (!ret)
- ret = "unixTEXT";
-
- sscanf(ret, "%4s%4s", creator, type);
-
- creator[4] = type[4] = '\0';
-
- printf("%s %s\n", creator, type);
-
-
- exit(0);
- }
- #endif /* MAIN */
-
-